#include <iostream>
using std::endl;
using std::cout;
using std::cin;

#include <vector>

struct matrixTerm
{ // 三元组结构体定义
    int row, col, value;

    matrixTerm(int row_ = 0, int col_ = 0, int val_ = 0)
        : row(row_)
        , col(col_)
        , value(val_)
    {

    }

    matrixTerm& operator=(const matrixTerm& x)
    { // 运算符重载 ，赋值*this = x
        row = x.row;
        col = x.col;
        value = x.value;
        return *this;
    }
};
const int maxsize = 199999; // 新matrixTerm创建最大容量设定

class sparseMatrix // 稀疏矩阵类定义
{
private:
    int Rows;            // 行
    int Cols;            // 列
    int Terms;           // 非零元素个数
    std::vector<matrixTerm> element; // 用来存非零元素的数组
    int maxSize;         // 数组最大容量
public:
    sparseMatrix(int n, int m) // 构造函数
        : element(199999)
    {
        //element = new matrixTerm[maxsize];
        Rows = n;
        Cols = m;
        Terms = 0;
    }
    sparseMatrix(int n, int m, int my) // 构造函数
    {
        //element = new matrixTerm[maxsize];
        Rows = n;
        Cols = m;
        Terms = 0;
    }

    sparseMatrix(int n, int m, char x) // 构造函数
    {
        //element = new matrixTerm[maxsize];
        std::vector<matrixTerm> element1(199999);
        element = element1;
        Rows = n;
        Cols = m;
        Terms = 0;
    }

    // ~sparseMatrix() { delete[] element; } // 析构函数

    void clear();
    int get(int row, int col);

    sparseMatrix& operator=(sparseMatrix& a)
    { // 运算符重载 ，赋值*this = a
        Rows = a.Rows;
        Cols = a.Cols;
        Terms = a.Terms;
        maxSize = a.maxSize;
        //for (int i = 0; i < Terms; i++)
        //    element[i] = a.element[i];
        element = a.element;
        return *this;
    }
    void inputAelement(int x, int y, int v); // 辅助函数——非0值输入
    void initial();              // 重置1
    int add(sparseMatrix& a);                // 加法3
    void output();                           // 输出4
};

// 辅助函数——非0值输入，更新三元组
void sparseMatrix::inputAelement(int x, int y, int v)
{
    matrixTerm New;
    New.row = x;   // 行序号
    New.col = y;   // 列序号
    New.value = v; // 非零元素值
    element.push_back(New);
    //element[Terms] = New;
    Terms++;
}

void sparseMatrix::clear()
{
    Rows = 0;
    Cols = 0;
    Terms = 0;
    element.clear();
}

// 重置1
void sparseMatrix::initial()
{
    clear();
    sparseMatrix PP(Rows, Cols, 20);
    int n = 0;
    int m = 0;
    cin >> n >> m;
    Rows = n;
    Cols = m;
    Terms = 0;
    for (int i = 1; i <= Rows; ++i)
    { // 按行优先顺序输入矩阵的各个元素
        for (int j = 1; j <= Cols; ++j)
        {
            int b;
            cin >> b;
            if (b != 0)
            {
                matrixTerm tmp(i, j, b);
                element.push_back(tmp);
                // element[Terms].row = i;
                // element[Terms].col = j;
                // element[Terms].value = b;
                Terms++;
            }
        }
    }


}



// 加法3
int sparseMatrix::add(sparseMatrix& Q)
{
    if (Q.Cols != Cols || Q.Rows != Rows) // 根据矩阵加法规则，行列不等不符合
    {
        *this = Q;
        return -1;
    }
    else
    {
        sparseMatrix C(Rows, Cols, 10); // 设置结果矩阵的特征
        //C.element.resize(19999);
        int it = 0, ib = 0;
        while (it < element.size() && ib < Q.element.size()) // 遍历，把相关的项相加
        {                                    // 行主索引加上每一项的列数
            int tIndex = (element[it].row-1) * Cols + element[it].col;
            int bIndex = (Q.element[ib].row - 1) * Cols + Q.element[ib].col;
            if (tIndex < bIndex)
            { // Q项在后
                matrixTerm tmp(element[it].row, element[it].col, element[it].value);
                C.element.push_back(tmp);
                it++;
              
            }
            else if (tIndex == bIndex)
            { // 两项在同一个位置
                if ((element[it]).value + (Q.element[ib]).value != 0)
                { // 仅当相加后不为0时加入c
                    matrixTerm tmp(element[it].row, element[it].col, element[it].value + Q.element[ib].value);
                    C.element.push_back(tmp);
                    
                }
                it++;
                ib++;
            }
            else
            {
                matrixTerm tmp(Q.element[ib].row, Q.element[ib].col, Q.element[ib].value);
                C.element.push_back(tmp);
                ib++;
                
            }
        }
        // 复制剩余项
        while (it < element.size())
        //for (; it < element.size(); it++)
        {
            matrixTerm tmp(element[it].row, element[it].col, element[it].value);
            C.element.push_back(tmp);
            
            it++;
        }
        while (ib < Q.element.size())
        //for (; ib < Q.element.size(); ib++)
        {
            matrixTerm tmp(Q.element[ib].row, Q.element[ib].col, Q.element[ib].value);
            C.element.push_back(tmp);
            
            ib++;
        }

        C.Terms = C.element.size();
        //*this = C;

        Rows = C.Rows;
        Cols = C.Cols;
        Terms = C.Terms;
        maxSize = C.maxSize;
        //for (int i = 0; i < Terms; i++)
        //    element[i] = a.element[i];
        element = C.element;

        return 0;
    }
}

// 
int sparseMatrix::get(int row, int col)
{
    for (int i = 0; i < element.size(); ++i)
    {
        if (element[i].row == row && element[i].col == col)
        {
            return element[i].value;
        }
    }

    return 0;
}

// 输出4
void sparseMatrix::output()
{
    int i, j, k = 0;
    cout << Rows << " " << Cols << endl;
    for (i = 1; i <= Rows; i++) // 遍历输出
    {
        for (j = 1; j <= Cols; j++)
        {
            if (k < element.size() && element[k].row == i + 1 && element[k].col == j + 1)
            {
                cout << element[k].value << " ";
                k++;
            }
            else
                cout << 0 << " ";
        }
        cout << endl;
    }
}


int main()
{
    sparseMatrix P(0, 0, 20);
    int w;           // 操作个数
    int panduan = 0; // 各种不合法输出工具变量
    int n;           // 矩阵行数
    int m;           // 矩阵列数
    int t;           // 矩阵非0元素个数
    int trans;       // 操作编码
    cin >> w;
    for (int i = 0; i < w; i++)
    {
        cin >> trans;
        switch (trans)
        {
            // 重置矩阵
            case 1:
            {
                P.initial();
                break;
            }

            // 矩阵乘法
            case 2:
            {
                break;
            }

            // 矩阵加法
            case 3:
            {
                cin >> n >> m;
                cin >> t;
                sparseMatrix Q2(n, m, 2);
                for (int i = 0; i < t; i++)
                {
                    int x, y, v;
                    cin >> x >> y >> v;
                    Q2.inputAelement(x, y, v);
                }
                panduan = P.add(Q2);
                if (panduan == -1)
                    cout << panduan << endl;
                break;

            }

            // 输出操作
            case 4:
            {
                P.output();
                break;
            }

            // 转置
            case 5:
            {
                break;
            }


        }
    }
    return 0;
}
